﻿using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Security.Cryptography;
using System;
using System.Text;
using System.Net;
using System.Threading;

namespace my_proxy.Utils
{


    public class FileReader
    {
        private Mutex m;
        private byte[] desKey;          // Encryption Key
        private byte[] desIV;           // Encryption Initial Vector

        public FileReader()
        {
            desKey = UTF8Encoding.UTF8.GetBytes("abcdefghijklmnop");
            desIV = UTF8Encoding.UTF8.GetBytes("00000000");
            m = new Mutex();
        }
		//bla bla
        public List<string> ReadList(string fileName)
        {
            if (File.Exists(fileName))
                return System.IO.File.ReadAllLines(fileName).ToList<string>();
            System.IO.File.Create(fileName);
            return null;
        }

     
      
        // thie method adda a user ip to the whitelist
        public void addEncryptedUser(string User,string fName)
        {
            m.WaitOne();
            try
            {
                StreamWriter sw = new StreamWriter(File.Open(fName,FileMode.Append));
                string newIP = encryptData(User);
                sw.WriteLine(newIP);
                sw.Close();
                m.ReleaseMutex();
            }
            catch (Exception e)
            {
                m.ReleaseMutex();
                Console.WriteLine(e.Message);
            }         
        }
        

        // this method creates an encrypted txt file of a given file.
        public void CreateEncryptedBlackListFile(string plainList, string EncryptedList)
        {
            FileStream fout = new FileStream(EncryptedList, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fout);
            sw.Flush();

            List<string> lines = ReadList(plainList);
            string lineEncrypted = "";
            foreach (string line in lines)
            {
                lineEncrypted = encryptData(line);
                sw.WriteLine(lineEncrypted);
            }
            sw.Close();
            fout.Close();
        }

        // this is a private method that recives a string and return an encrypted string
        private string encryptData(string plainText)
        {
            TripleDES Tdes = new TripleDESCryptoServiceProvider();
            Tdes.Mode = CipherMode.CBC;
            Tdes.Padding = PaddingMode.PKCS7;
            Tdes.IV = new byte[8];
            Tdes.Key = desKey;
            ICryptoTransform encryptor = Tdes.CreateEncryptor();
            byte[] plainTextArray = UTF8Encoding.UTF8.GetBytes(plainText);
            byte[] encTextArray = encryptor.TransformFinalBlock(plainTextArray, 0, plainTextArray.Length);
            return Convert.ToBase64String(encTextArray, 0, encTextArray.Length);
        }

        // this  method recives a txt-file name and returns the decrypted version of it in  a list
        public List<string> getDecryptedList(string fileName)
        {
            List<string> res = new List<string>();
            List<string> lines = ReadList(fileName);
            string line = "";
            foreach (string lineEncrypted in lines)
            {
                line = decryptData(lineEncrypted);
                res.Add(line);
            }
            return res;
        }

        //   this is a private method that recives an encrypted string and returns a decrypted string
        private string decryptData(string encText)
        {
            TripleDES Tdes = new TripleDESCryptoServiceProvider();
            Tdes.Mode = CipherMode.CBC;
            Tdes.Padding = PaddingMode.PKCS7;
            Tdes.IV = new byte[8];
            Tdes.Key = desKey;

            ICryptoTransform decryptor = Tdes.CreateDecryptor();
            byte[] encTextArray = Convert.FromBase64String(encText);
            byte[] plainTextArray = decryptor.TransformFinalBlock(encTextArray, 0, encTextArray.Length);
            return UTF8Encoding.UTF8.GetString(plainTextArray, 0, plainTextArray.Length);
        }

       

        // not sure if i'll need this method
        public static string BinaryToString(string data)
        {
            List<Byte> byteList = new List<Byte>();

            for (int i = 0; i < data.Length; i += 8)
            {
                byteList.Add(Convert.ToByte(data.Substring(i, 8), 2));
            }

            return Encoding.ASCII.GetString(byteList.ToArray());
        }
    }
}
